package com.my.jli.Service.impl;

import com.my.jli.Service.ExerciseService;
import com.my.jli.dao.*;
import com.my.jli.entity.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * @ClassName ExerciseServiceImpl
 * @Description
 * @Author MaYu
 * @Date 2022/4/11 19:17
 * @Version 1.0
 **/
@Service
public class ExerciseServiceImpl implements ExerciseService {

    Logger logger = LoggerFactory.getLogger(ExerciseServiceImpl.class);

    private ExerciseRepository exerciseRepository;
    private ExerciseOptionRepository exerciseOptionRepository;
    private ExerciseTypeRepository exerciseTypeRepository;
    private ExerciseChapterRepository exerciseChapterRepository;
    private ExerciseAndStudentRepository exerciseAndStudentRepository;
    @Autowired
    public void setExerciseRepository(ExerciseRepository exerciseRepository) {
        this.exerciseRepository = exerciseRepository;
    }
    @Autowired
    public void setExerciseOptionRepository(ExerciseOptionRepository exerciseOptionRepository) {
        this.exerciseOptionRepository = exerciseOptionRepository;
    }
    @Autowired
    public void setExerciseTypeRepository(ExerciseTypeRepository exerciseTypeRepository) {
        this.exerciseTypeRepository = exerciseTypeRepository;
    }
    @Autowired
    public void setExerciseChapterRepository(ExerciseChapterRepository exerciseChapterRepository) {
        this.exerciseChapterRepository = exerciseChapterRepository;
    }
    @Autowired
    public void setExerciseAndStudentRepository(ExerciseAndStudentRepository exerciseAndStudentRepository) {
        this.exerciseAndStudentRepository = exerciseAndStudentRepository;
    }

    @Override
    @Transactional(readOnly = true)
    public Map<Exercise, ExerciseOption> findAll() {
        logger.info("执行了获取exercise=>exerciseOption map的业务方法");
        Map<Exercise, ExerciseOption> map = new HashMap<>();
        List<Exercise> exerciseList = exerciseRepository.findAll();
        for (Exercise exercise : exerciseList) {
            ExerciseOption option = exerciseOptionRepository.findByEid(exercise.getId());
            map.put(exercise, option);
        }
        return map;
    }

    @Override
    @Transactional(readOnly = true)
    public Page<Exercise> findAll(Pageable pageable) {
        logger.info("执行了分页获取习题信息的业务");
        return exerciseRepository.findAll(pageable);
    }

    @Override
    @Transactional(readOnly = true)
    public Page<Exercise> findAll(Example<Exercise> example, Pageable pageable) {
        logger.info("执行了分页（带查询）获取习题信息的业务");
        return exerciseRepository.findAll(example, pageable);
    }

    @Override
    @Transactional(readOnly = true)
    public Exercise findExerciseById(Integer id) {
        logger.info("执行了通过id获取习题信息的业务");
        Optional<Exercise> exerciseOptional = exerciseRepository.findById(id);
        return exerciseOptional.orElse(null);
    }

    @Override
    @Transactional(readOnly = true)
    public ExerciseOption findOptionByEid(Integer eid) {
        logger.info("执行了通过习题id获取选项的业务");
        return exerciseOptionRepository.findByEid(eid);
    }

    @Override
    @Transactional(readOnly = true)
    public List<ExerciseType> findAllType() {
        logger.info("执行了获取所有习题类型的业务");
        return exerciseTypeRepository.findAll();
    }

    @Override
    @Transactional(readOnly = true)
    public List<ExerciseChapter> findAllChapter() {
        logger.info("执行了获取所有习题章节的业务");
        return exerciseChapterRepository.findAll();
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED)
    public Integer saveExercise(Exercise exercise) {
        logger.info("执行了添加习题的业务");
        Exercise save = exerciseRepository.save(exercise);
        return save.getId();
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED)
    public void saveExercise(Exercise exercise, ExerciseOption option) {
        logger.info("执行了添加习题的业务");
        Exercise exercise1 = exerciseRepository.save(exercise);
        option.setEid(exercise1.getId());
        exerciseOptionRepository.save(option);
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED)
    public void saveExerciseOption(ExerciseOption option) {
        logger.info("执行了添加习题选项的业务");
        exerciseOptionRepository.save(option);
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED)
    public void saveExerciseChapter(ExerciseChapter chapter) {
        logger.info("执行了添加习题章节的业务");
        exerciseChapterRepository.save(chapter);
    }

    @Override
    @Transactional(readOnly = true)
    public ExerciseChapter findChapterByName(String chapterName) {
        logger.info("执行了通过名称获取章节的业务");
        return exerciseChapterRepository.findByName(chapterName);
    }

    @Override
    @Transactional(readOnly = true)
    public ExerciseType findTypeByName(String typeName) {
        logger.info("执行了通过名称获取习题类型的业务");
        return exerciseTypeRepository.findByName(typeName);
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED)
    public void deleteExerciseById(Integer id) {
        logger.info("执行了通过id删除习题的业务");
        exerciseRepository.deleteById(id);
    }

    @Override
    @Transactional(readOnly = true)
    public double getCompletionRate(Integer cId, Integer sId) {
        logger.info("执行了获取章节完成率的业务");
        //首先获得该章节所有习题
        List<Exercise> exerciseList = exerciseRepository.findByChapter(cId);
        //再获取该章节该学生已完成的习题个数
        int completeCount = 0;
        for (Exercise exercise : exerciseList) {
            ExerciseAndStudent es = exerciseAndStudentRepository.findByEidAndSid(exercise.getId(), sId);
            if (es != null){
                completeCount++;
            }
        }
        return (double) completeCount / exerciseList.size();
    }

    @Override
    @Transactional(readOnly = true)
    public List<Exercise> getExerciseByCid(Integer cId) {
        logger.info("执行了根据章节id获取习题的业务");
        //获取该章节所有习题
        return exerciseRepository.findByChapter(cId);
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED)
    public ExerciseAndStudent saveExerciseAndStudent(ExerciseAndStudent es) {
        return exerciseAndStudentRepository.save(es);
    }

    @Override
    @Transactional(readOnly = true)
    public ExerciseAndStudent findESByEidAndSid(Integer eid, Integer sid) {
        return exerciseAndStudentRepository.findByEidAndSid(eid, sid);
    }
}
